/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.config.mongo;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@Configuration
public class MongoConfig {

    @Autowired
    private PrimaryMongoProperties primaryMongoProperties; // 主数据源属性

    @Autowired
    private SecondaryMongoProperties secondaryMongoProperties; // 次数据源属性，载荷库

    // 主数据源
    @Primary
    @Bean(name = "primaryMongoClient")
    public MongoClient primaryMongoClient() {
        try {
            String encodedUsername = URLEncoder.encode(primaryMongoProperties.getUsername(), StandardCharsets.UTF_8);
            String encodedPassword = URLEncoder.encode(primaryMongoProperties.getPassword(), StandardCharsets.UTF_8);

            String connectionString = String.format("mongodb://%s:%s@%s:%d/%s?authSource=%s",
                encodedUsername,
                encodedPassword,
                primaryMongoProperties.getHost(),
                primaryMongoProperties.getPort(),
                primaryMongoProperties.getDatabase(),
                primaryMongoProperties.getAuthenticationDatabase());
            return MongoClients.create(connectionString);
        } catch (Exception e) {
            throw new RuntimeException("Failed to create MongoDB client", e);
        }
    }

    // 次数据源
    @Bean(name = "secondaryMongoClient")
    public MongoClient secondaryMongoClient() {
        try {
            String encodedUsername = URLEncoder.encode(secondaryMongoProperties.getUsername(), StandardCharsets.UTF_8);
            String encodedPassword = URLEncoder.encode(secondaryMongoProperties.getPassword(), StandardCharsets.UTF_8);

            String connectionString = String.format("mongodb://%s:%s@%s:%d/%s?authSource=%s",
                encodedUsername,
                encodedPassword,
                secondaryMongoProperties.getHost(),
                secondaryMongoProperties.getPort(),
                secondaryMongoProperties.getDatabase(),
                secondaryMongoProperties.getAuthenticationDatabase());
            return MongoClients.create(connectionString);
        } catch (Exception e) {
            throw new RuntimeException("Failed to create MongoDB client", e);
        }
    }

    // 主MongoDatabaseFactory
    @Primary
    @Bean(name = "primaryMongoDbFactory")
    public MongoDatabaseFactory primaryMongoDbFactory(@Qualifier("primaryMongoClient") MongoClient mongoClient) {
        return new SimpleMongoClientDatabaseFactory(mongoClient, primaryMongoProperties.getDatabase());
    }

    // 次MongoDatabaseFactory
    @Bean(name = "secondaryMongoDbFactory")
    public MongoDatabaseFactory secondaryMongoDbFactory(@Qualifier("secondaryMongoClient") MongoClient mongoClient) {
        return new SimpleMongoClientDatabaseFactory(mongoClient, secondaryMongoProperties.getDatabase());
    }

    // 主MongoTemplate
    @Primary
    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate primaryMongoTemplate(@Qualifier("primaryMongoDbFactory") MongoDatabaseFactory mongoDbFactory) {
        return new MongoTemplate(mongoDbFactory);
    }

    // 次MongoTemplate
    @Bean(name = "secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate(@Qualifier("secondaryMongoDbFactory") MongoDatabaseFactory mongoDbFactory) {
        return new MongoTemplate(mongoDbFactory);
    }

    // GridFsTemplate
    @Bean(name = "gridFsTemplate")
    public GridFsTemplate gridFsTemplate(@Qualifier("secondaryMongoTemplate") MongoTemplate secondaryMongoTemplate) {
        return new GridFsTemplate(
            secondaryMongoTemplate.getMongoDatabaseFactory(),
            secondaryMongoTemplate.getConverter()
        );
    }
}
